package io.gitee.kotle.demo.mvvm_demo.websocket

import android.content.Context
import android.os.Bundle
import android.view.inputmethod.EditorInfo
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.LinearLayoutManager
import io.gitee.kotle.android.adapter.recyclerViewAdapter
import io.gitee.kotle.android.adapter.refreshList
import io.gitee.kotle.android.adapter.scrollToPositionWithOffset
import io.gitee.kotle.android.delegate.unsafeLazy
import io.gitee.kotle.android.library.websocket.IWebSocket
import io.gitee.kotle.android.library.websocket.WebSocketHelper
import io.gitee.kotle.android.library.websocket.WebSocketStatus
import io.gitee.kotle.android.library.websocket.createWebSocket
import io.gitee.kotle.android.utils.*
import io.gitee.kotle.base.library.BaseBindingFragment
import io.gitee.kotle.demo.databinding.FragmentWebSocketBinding
import kotlin.math.max

class WebSocketFragment : BaseBindingFragment<FragmentWebSocketBinding>() {
    companion object {
        fun start(context: Context) {
            context.startFragment<WebSocketFragment>()
        }
    }

    private val webSocket by unsafeLazy {
        val client = OkHttpCertUtil.createCertOkHttpBuilder()
            .addInterceptor {
                val request = it.request().newBuilder()
                request.addHeader("Origin", "http://coolaf.com")
                it.proceed(request.build())
            }
            .build()
        WebSocketHelper(createWebSocket(client), "ws://82.157.123.54:9010/ajaxchattest") {
            appendItem(WebSocketReceiveHolder.Bean(it))
            scrollEnd(false)
        }
    }
    private val manager by unsafeLazy { LinearLayoutManager(requireContext()) }
    private val adapter = recyclerViewAdapter<Any>().also {
        it.register(WebSocketReceiveHolder::class.java)
        it.register(WebSocketSendHolder::class.java)
        it.register(WebSocketLastPositionHolder::class.java)
        it.refreshList(listOf(WebSocketLastPositionHolder.Bean()))
    }


    override fun initUi(savedInstanceState: Bundle?) {
        super.initUi(savedInstanceState)
        var lastStatusBarsHeight = 0
        var lastNavigationBarHeight = 0
        transparentStatusBar(
            true,
            isBlackNavigationBarTextColor = true
        ) { insets: WindowInsetsCompat, statusBarsHeight: Int, navigationBarHeight: Int ->
            if (lastStatusBarsHeight != statusBarsHeight) {
                lastStatusBarsHeight = statusBarsHeight
                mBinding.root.updatePadding(top = statusBarsHeight)
            }
            if (lastNavigationBarHeight != navigationBarHeight) {
                lastNavigationBarHeight = navigationBarHeight
                mBinding.root.updatePadding(bottom = navigationBarHeight)
            }
            insets
        }
        webSocket.webSocket.addListener(object : IWebSocket.Listener {
            override fun onConnectStatus(status: WebSocketStatus) {
                super.onConnectStatus(status)
                mBinding.tvStatus.text =
                    if (status == WebSocketStatus.ConnectSuccess) "连接成功" else "未连接"
            }
        })
        mBinding.rcv.adapter = adapter
        mBinding.etInput.onAction(EditorInfo.IME_ACTION_SEND) {
            if (it.isNotBlank()) {
                appendItem(WebSocketSendHolder.Bean(it))
                scrollEnd()
                webSocket.sendMessage(it, true)
                mBinding.etInput.text = null
            }
        }
        manager.stackFromEnd = true
        mBinding.rcv.layoutManager = manager
        ImeHelper.invoke(this)
            .setOnImeListener { imeOffset, imeMaxHeight, statusBarHeight, navigationBarHeight ->
                mBinding.root.updatePadding(
                    bottom = max(imeOffset, navigationBarHeight),
                    top = statusBarHeight
                )
                scrollEnd()
            }
    }

    private fun scrollEnd(always: Boolean = true) {
        if (!always) {
            if (!mBinding.rcv.hadScrollToBottom()) {
                return
            }
        }
        val lastPosition = adapter.itemCount - 1
        mBinding.rcv.scrollToPositionWithOffset(lastPosition)
    }


    private fun appendItem(any: Any) {
        adapter.addItem(any, adapter.itemCount - 1)
    }


    override fun onDestroy() {
        super.onDestroy()
        webSocket.destroy()
    }
}